﻿using MvvmCross.Core.ViewModels;
using Sidvall.WorkItemManager.Data;
using Sidvall.WorkItemManager.UI.Entities;
using Sidvall.WorkItemManager.UI.Messaging;
using System.Threading.Tasks;
using System.Windows.Input;

namespace Sidvall.WorkItemManager.UI.ViewModels
{
    public partial class WebContextViewModel
    {
        #region Public Members

        #region CanEdit

        private bool _CanEdit;
        public bool CanEdit
        {
            get
            {
                return _CanEdit;
            }
            set
            {
                if (_CanEdit == value)
                    return;
                _CanEdit = value;
                RaisePropertyChanged(nameof(CanEdit));
            }
        }

        #endregion
        #region Context

        private string _Context;
        public string Context
        {
            get
            {
                return _Context;
            }
            set
            {
                if (_Context == value)
                    return;
                _Context = value;
                RaisePropertyChanged("Context");
                OnContextChanged();
            }
        }

        #endregion
        #region ActiveWebTarget

        private WebTarget _ActiveWebTarget;
        public WebTarget ActiveWebTarget
        {
            get
            {
                return _ActiveWebTarget;
            }
            set
            {
                if (_ActiveWebTarget != null)
                    _ActiveWebTarget.PropertyChanged -= OnActiveWebTargetPropertyChanged;
                _ActiveWebTarget = value;
                if (_ActiveWebTarget != null)
                    _ActiveWebTarget.PropertyChanged += OnActiveWebTargetPropertyChanged;
                RaisePropertyChanged("ActiveWebTarget");
            }
        }

        #endregion
        #region WebTargetListIsVisible

        public bool WebTargetListIsVisible
        {
            get
            {
                return _WebTargetListIsVisible;
            }
            set
            {
                _WebTargetListIsVisible = value;
                RaisePropertyChanged("WebTargetListIsVisible");
            }
        }

        #endregion
        #region HttpVerbs

        private HttpVerbCollection _HttpVerbs;
        public HttpVerbCollection HttpVerbs
        {
            get
            {
                if (_HttpVerbs == null)
                    _HttpVerbs = HttpVerbCollection.Create();
                return _HttpVerbs;
            }
            private set
            {
                _HttpVerbs = value;
                RaisePropertyChanged("HttpVerbs");
            }
        }

        #endregion

        #region AddWebTargetCommand

        public ICommand AddWebTargetCommand
        {
            get
            {
                return new MvxCommand(AddWebTarget);
            }
        }

        #endregion
        #region AddWebTarget

        public void AddWebTarget()
        {
            WebTarget item;

            if (this.ActiveEntity == null)
                return;

            item = new WebTarget()
            {
                IsEnabled = true,
            };
            if (this.ActiveEntity.WebContextId != null)
                item.WebContextId = this.ActiveEntity.WebContextId.Value;
            this.ActiveEntity.WebTargets.Add(item);
            this.ActiveWebTarget = item;
            this.WebTargetListIsVisible = false;
        }

        #endregion
        #region DeleteWebTargetCommand

        public ICommand DeleteWebTargetCommand
        {
            get
            {
                return new MvxCommand<WebTarget>(DeleteWebTarget);
            }
        }

        #endregion
        #region DeleteWebTarget

        public void DeleteWebTarget(WebTarget item)
        {
            if (this.ActiveEntity == null)
                return;
            if (item == null)
                return;
            this.ActiveEntity.WebTargets.Remove(item);
        }

        #endregion
        #region EditWebTargetCommand

        public ICommand EditWebTargetCommand
        {
            get
            {
                return new MvxCommand<WebTarget>(EditWebTarget);
            }
        }

        #endregion
        #region EditWebTarget

        public void EditWebTarget(WebTarget item)
        {
            if (this.ActiveEntity == null)
                return;
            if (item == null)
                return;
            this.ActiveWebTarget = item;
            this.WebTargetListIsVisible = false;
        }

        #endregion
        #region ShowWebTargetListCommand

        public ICommand ShowWebTargetListCommand
        {
            get
            {
                return new MvxCommand(ShowWebTargetList);
            }
        }

        #endregion
        #region ShowWebTargetList

        public void ShowWebTargetList()
        {
            this.WebTargetListIsVisible = true;
        }

        #endregion
        #region OpenWebTargetCommand

        public ICommand OpenWebTargetCommand
        {
            get
            {
                return new MvxCommand<WebTarget>(async (o) => await OpenWebTargetAsync(o));
            }
        }

        #endregion
        #region OpenWebTargetAsync

        public async Task OpenWebTargetAsync(WebTarget item)
        {
            Task task = null;
            try
            {
                if (this.ActiveEntity == null)
                    return;
                if (item == null)
                    return;
                await Sidvall.SystemContext.Current.LauncherManager.LaunchFileAsync(item.WebAddress);
            }
            catch (System.Exception ex)
            {
                task = Sidvall.UI.SystemContext.Current.DialogManager.ShowErrorMessageAsync("Open Error", ex);
            }
            if (task != null)
                await task;

        }

        #endregion

        #region OnActiveEntityChanged

        protected override void OnActiveEntityChanged(Sidvall.Business.BusinessObjectChangeMode changeMode, Sidvall.Business.ChildChangedEventArgs childArgs, System.ComponentModel.PropertyChangedEventArgs propertyArgs)
        {
            if (this.ActiveEntity.WebTargets == null)
                this.ActiveEntity.WebTargets = new WebTargetCollection();
            this.Context = WebContext.Serialize(this.ActiveEntity);
        }

        #endregion
        #region OnContextChanged

        protected virtual void OnContextChanged()
        {
            if (this.PublishChange)
            {
                var message = new WorkItemContextMessage(this)
                {
                    Context = this.Context,
                    CanEdit = this.CanEdit,
                };
                Publish(message);
            }
        }

        #endregion
        #region OnViewEvent

        protected override async Task OnViewEventAsync(Sidvall.UI.Views.ViewEventArgs args)
        {
            if (this.IsSavable)
                this.IsSavable = false;
            await base.OnViewEventAsync(args);
        }

        #endregion

        #region Init

        public void Init(ContextParameter item)
        {
            this.ContextParameter = item;
        }

        #endregion
        #region InitializeContext

        public virtual void InitializeContext()
        {
            this.ActiveEntity = WebContext.Deserialize(this.Context);
        }

        #endregion
        #region StartAsync

        protected override Task StartAsync()
        {
            _WebTargetListIsVisible = true;

            Subscribe<WorkItemContextMessage>(OnWorkItemContextMessage);
            Subscribe<WorkItemExecutionContextMessage>(OnWorkItemExecutionContextMessage);
            if (this.ContextParameter != null)
            {
                this.PublishChange = false;
                this.Context = this.ContextParameter.Context;
                this.PublishChange = true;
                InitializeContext();
                this.ContextParameter = null;
            }
            return Task.FromResult(true);
        }

        #endregion

        #endregion
        #region Private Members

        private bool _WebTargetListIsVisible = false;

        private ContextParameter ContextParameter { get; set; }
        private WebExecutionContext ExecutionContext { get; set; }
        private bool PublishChange { get; set; }

        #region InitializeExecutionContext

        private void InitializeExecutionContext()
        {
            if (this.ExecutionContext == null)
                return;
            if (this.ActiveEntity == null)
                return;
            this.ActiveEntity.LoadWebResult(this.ExecutionContext.WebResults);
            this.ExecutionContext = null;
        }

        #endregion

        #region OnActiveWebTargetPropertyChanged

        private void OnActiveWebTargetPropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
        {
        }

        #endregion
        #region OnWorkItemContextMessage

        private void OnWorkItemContextMessage(WorkItemContextMessage item)
        {
            this.CanEdit = item.CanEdit;
            if (this.Context == item.Context)
                return;
            this.PublishChange = false;
            this.Context = item.Context;
            this.PublishChange = true;
            InitializeContext();
            InitializeExecutionContext();
        }

        #endregion
        #region OnWorkItemExecutionContextMessage

        private void OnWorkItemExecutionContextMessage(WorkItemExecutionContextMessage item)
        {
            this.ExecutionContext = WebExecutionContext.Deserialize(item.Context);
            InitializeExecutionContext();
        }

        #endregion

        #endregion
    }
}